//第一题 下列代码执行结果
var a=[]
for(var i=0;i<10;i++){
    a[i] = function(){
        console.log(i)
    }
}
a[6]()

//最终打印的是10，因为函数内部指向的i为for循环定义的i，在循环结束后变为10

//第二题 下列代码执行结果
var tmp = '123'
if(true){
    console.log(tmp)
    let tmp
}

//报错，因为let不存在变量提升，在if作用域内部先使用后声明，最终运行会报错。

//第三题 用ES6找出数组中的最小值
var arr = [12,34,32,89,4]
let num = (arr) => Math.min(...arr);
num(arr)

//第四题 var、let、const之间的区别
/*
var 存在变量提升、声明的变量会挂载到全局作用域上
let\const 不存在变量提升，且变量只存在于当前作用域中
const 声明后不可更改
*/

//第五题 下列代码的结果
var a = 10
var obj={
    a:20,
    fn(){
        setTimeout(() => {
            console.log(this.a)
        });
    }
}
obj.fn()

//最终输出20，因为箭头函数继承父执行上下文里面的this ，所以this指向fn的this也就是obj

//第六题 简述Symbol
/* 
symbol 是一种新的基本类型
通过symbol可以定义一个独一无二的变量，哪怕生成的key值一样也不会重复
同时symbol不可以通过常用的遍历方式获取
因此symbol常用来解决重复命名以及私有变量的声明
*/


//第七题 深拷贝、浅拷贝
/*
因为JS的存储方式分为两类， 基本数据类型存储在栈中，引用数据类型存储在堆中
浅拷贝只赋值了值和堆的引用，并不会创建新的地址，因此引用类型数据修改时原数据也会改变
深拷贝会创建新的地址将引用类型完全复制，拷贝后的对象和原对象互不干扰
*/

//第八题 TS和JS的关系
/*
TS是JS的超集，在JS的基础上添加了类型检查系统和对ES6的支持
帮助在开发过程中解决JS运行时的类型错误
*/

//第九题 TS优缺点
/* 
优点：
完善的类型检查机制可以在编译阶段就发现大部分错误
新特性可以帮助节省开发的时间
渐进式的特点可以比较好的兼容老代码
增加了代码可维护性

缺点：
初期会有一定的学习成本
目前不是所有的库都支持TS
*/

//第十题 引用计数的工作原理和优缺点
/*
引用计数会对变量的引用用引用计数器进行计算，当变量被引用时+1，不引用时-1
当变量引用为0时算为垃圾进行回收

优点：
发现垃圾时立即回收
最大限度减少程序暂停

缺点：
无法回收循环引用的对象
时间开销大（时刻监控）
*/

//第十一题 标记整理算法的工作流程
/*
在GC开始时，从根开始遍历并标记存活的变量
标记结束后，将已标记的变量进行内存整理，整理到内存的一端
然后将未标记的变量清除
*/

//第十二题 V8中的新生代垃圾回收流程
/* 
新生代有两个空间from和to，存活的对象储存于from空间
在GC开始时，使用标记整理算法将存活的变量赋值到To
清空from
最后再把to复制回from

如果一轮GC后还存活的变量或者to空间超过25%时则会把新生代对象晋升到老生代
*/

//第十三题 增量标记算法
/*
老生代的GC回收即使用增量标记算法
增量标记指将一次完整的标记清除工作分为若干部分，在程序运行的空档进行，以免阻塞主程序执行
*/